/**
 * Copyright 2011 FeedDreamwork SIG
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

package org.feeddreamwork.feed;

import java.text.*;
import java.util.*;
import org.feeddreamwork.*;
import org.w3c.dom.*;

public class Rss20FeedParser extends FeedParser {
	@Override
	public boolean isThisType(Document source) {
		Element root = source.getDocumentElement();
		if (root.getNodeName().equals("rss")
				&& "2.0".equals(root.getAttribute("version")))
			return true;
		else
			return false;
	}

	@Override
	public Feed parse(Document source, String baseURL)
			throws FeedParsingException {
		Element rss = source.getDocumentElement();
		Element channel = null;
		NodeList rssChildNodes = rss.getChildNodes();
		for (int i = 0; i < rssChildNodes.getLength(); i++)
			if (rssChildNodes.item(i).getNodeName().equals("channel")) {
				channel = (Element) rssChildNodes.item(i);
				break;
			}
		if (channel == null)
			throw new FeedParsingException();

		Feed feed = parseFeedMetadata(channel, baseURL);
		NodeList childNodes = channel.getChildNodes();
		for (int i = 0; i < childNodes.getLength(); i++)
			if (childNodes.item(i).getNodeName().equals("item")) {
				Element item = (Element) childNodes.item(i);
				feed.getEntries().add(parseEntry(feed, item, baseURL));
			}
		return feed;
	}

	@Override
	protected Feed parseFeedMetadata(Element root, String baseURL)
			throws FeedParsingException {
		String title = XMLUtils.findSimpleElement(root, "title");
		String link = XMLUtils.findSimpleElement(root, "link");
		if (Utils.isNullOrEmpty(title) || Utils.isNullOrEmpty(link))
			throw new FeedParsingException();
		link = resolveURL(root, link, baseURL);
		Feed feed = new Feed(title, link);

		feed.setDescription(XMLUtils.findSimpleElement(root, "description"));
		NodeList childNodes = root.getChildNodes();
		for (int i = 0; i < childNodes.getLength(); i++)
			if (childNodes.item(i).getNodeName().equals("image")) {
				String image = XMLUtils.findSimpleElement(
						(Element) childNodes.item(i), "url");
				feed.setImage(image);
			}
		feed.setLanguage(XMLUtils.findSimpleElement(root, "language"));
		return feed;
	}

	@Override
	protected Entry parseEntry(Feed feed, Element entry, String baseURL)
			throws FeedParsingException {
		String title = XMLUtils.findSimpleElement(entry, "title");
		if (Utils.isNullOrEmpty(title))
			title = feed.getTitle();
		String link = XMLUtils.findSimpleElement(entry, "link");
		String content = XMLUtils.findSimpleElement(entry, "content:encoded");
		if (Utils.isNullOrEmpty(content))
			content = XMLUtils.findSimpleElement(entry, "description");
		String author = XMLUtils.findSimpleElement(entry, "author");
		if (Utils.isNullOrEmpty(author))
			author = XMLUtils.findSimpleElement(entry, "dc:creator");
		if (Utils.isNullOrEmpty(author))
			author = feed.getTitle();
		String updatedTime = XMLUtils.findSimpleElement(entry, "pubDate");
		String publishedTime = XMLUtils.findSimpleElement(entry, "pubDate");
		if (Utils.isNullOrEmpty(updatedTime))
			updatedTime = DateUtils.formatDateAsRFC2822(new Date(0));

		if (Utils.isNullOrEmpty(link))
			throw new FeedParsingException();
		link = resolveURL(entry, link, baseURL);
		try {
			Entry result = new Entry(title, link, content, author,
					DateUtils.parseRFC2822Date(updatedTime));
			if (!Utils.isNullOrEmpty(publishedTime))
				result.setPublishedTime(DateUtils
						.parseRFC2822Date(publishedTime));
			return result;
		} catch (ParseException e) {
			throw new FeedParsingException();
		}
	}
}
